package com.bup.gn.utils;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.AbstractMessageSource;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public class JdbcMessageSource extends AbstractMessageSource implements
        InitializingBean {

    private JdbcTemplate jdbcTemplate;

    private Map<CacheKey, MessageFormat> cachedMessages = new HashMap<CacheKey, MessageFormat>();

    private static class CacheKey {
        public String code;

        public Locale locale;

        public CacheKey(String code, Locale locale) {
            this.code = code;
            this.locale = locale;
        }

        public boolean equals(Object obj) {
            CacheKey key = (CacheKey) obj;
            return key.code.equals(this.code) && key.locale == this.locale;
        }
    }

    protected MessageFormat resolveCode(String code, Locale locale) {
        MessageFormat result;

        result = resolveCodeInternal(code, locale);
        cachedMessages.put(new CacheKey(code, locale), result);

        if (result != null) {
            return result;
        }

        return resolveCodeInternal(code, locale);
    }

    private MessageFormat resolveCodeInternal(String code, Locale locale) {
        CacheKey key = new CacheKey(code, locale);
        if (cachedMessages.containsKey(key)) {
            return cachedMessages.get(key);
        } else {
            String finalResult = code;
            try {
                List<Map<String, Object>> result = jdbcTemplate.queryForList(
                        "SELECT message_value FROM Messages WHERE message_key = '" + code
                                + "' AND message_locale = '" + locale.toString() + "'");
                if (result != null && result.size() != 0) {
                    finalResult = result.get(0).get("message_value").toString();
                }
            } catch (IncorrectResultSizeDataAccessException ignored) {
            }
            MessageFormat messageFormat = new MessageFormat(finalResult, locale);
            cachedMessages.put(key, messageFormat);
            return messageFormat;
        }
    }

    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    public void afterPropertiesSet() throws Exception {
    }

    public void clearCache() {
        cachedMessages.clear();
    }
}
